package ac.neec.mio.ui.fragment;

import java.util.ArrayList;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import ac.neec.core.ble.util.BleUtil;
import ac.neec.listener.EventsCallBackListener;
import ac.neec.mio.R;
import ac.neec.mio.ui.activity.MeasurementActivity;
import ac.neec.mio.ui.adapter.BLEDeviceAdapter;
import android.app.Activity;
import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

/**
 * Created by kobayashi on 2014/01/26.
 */
public class ConnectBLEFlagment extends Fragment implements AdapterView.OnItemClickListener, View.OnClickListener {

	private static final int MESSAGE_SCANED_DEVICE = 0;
	private static final long REFRESH_DURATION = 10000;
	private boolean isScanning = false;
	private TextView deviceName;
	private TextView deviceMACAddress;
	private ImageView deviceImage;
	private Button connectButton;
	private ListView pairListView;
	private PullToRefreshListView discaListView;
	private BLEDeviceAdapter pairDeviceAdapter;
	private BLEDeviceAdapter discaDeviceAdapter;
	private BluetoothAdapter mBluetoothAdapter;
	private BluetoothDevice selectedDevice;
	private EventsCallBackListener mCallbackListener;
	private OnRefreshListener<ListView> mOnRefreshListener = new OnRefreshListener<ListView>() {
		@Override
		public void onRefresh(PullToRefreshBase<ListView> refreshView) {
			Timer timer = new Timer(true);
			timer.schedule(new TimerTask() {
				@Override
				public void run() {
					mHandler.post(new Runnable() {
						public void run() {
							discaListView.onRefreshComplete();
						}
					});
				}
			}, REFRESH_DURATION);
			if (isScanning == false) {
				scanLeDevice(false);
				Toast.makeText(getActivity(), "BLE Scan Stop", Toast.LENGTH_SHORT).show();
			}
			scanLeDevice(true);
			Toast.makeText(getActivity(), "Scaning BLE Device", Toast.LENGTH_SHORT).show();
		}
	};

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			mCallbackListener = (EventsCallBackListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
		}
	}

	@Override
	public void onCreate(Bundle savedStateInstance) {
		super.onCreate(savedStateInstance);

		// Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
		// BluetoothAdapter through BluetoothManager.
		final BluetoothManager bluetoothManager =
				(BluetoothManager) getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
		mBluetoothAdapter = bluetoothManager.getAdapter();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedStateInstance) {
		View view = inflater.inflate(R.layout.fragment_connect_ble, container, false);

		setLinkView(view);
		setLinkListener();

		pairDeviceAdapter = new BLEDeviceAdapter(getActivity(), R.layout.adapter_ble_device,
				new ArrayList<BluetoothDevice>());
		discaDeviceAdapter = new BLEDeviceAdapter(getActivity(), R.layout.adapter_ble_device,
				new ArrayList<BluetoothDevice>());

		pairListView.setAdapter(pairDeviceAdapter);
		discaListView.setAdapter(discaDeviceAdapter);

		discaListView.setPullLabel("Pull");
		discaListView.setRefreshingLabel("Scanning ........");
		discaListView.setReleaseLabel("Please Release");
		setupPairedDevice();

		return view;
	}

	private void setupPairedDevice() {
		// BluetoothAdapterから、接続履歴のあるデバイスの情報を取得
		Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
				.getBondedDevices();
		if (pairedDevices.size() > 0) {
			// 接続履歴のあるデバイスが存在する
			for (BluetoothDevice device : pairedDevices) {
				// 接続履歴のあるデバイスの情報を順に取得してアダプタに詰める
				// getName()・・・デバイス名取得メソッド
				// getAddress()・・・デバイスのMACアドレス取得メソッド
				pairDeviceAdapter.add(device);
			}
		}

	}

	private void setLinkView(View view) {
		deviceName = (TextView) view.findViewById(R.id.fragment_connect_device_name);
		deviceMACAddress = (TextView) view.findViewById(R.id.fragment_connect_device_mac_addr);
		deviceImage = (ImageView) view.findViewById(R.id.fragment_connect_device_image);
		connectButton = (Button) view.findViewById(R.id.fragment_connect_button_connect);

		pairListView = (ListView) view.findViewById(R.id.fragment_connect_listview_pair);
		discaListView = (PullToRefreshListView) view.findViewById(R.id.fragment_connect_listview_disca);
	}

	private void setLinkListener() {
		connectButton.setOnClickListener(this);
		pairListView.setOnItemClickListener(this);
//		discaListView.setOnItemClickListener( this );
		discaListView.getRefreshableView().setOnItemClickListener(this);
		discaListView.setOnRefreshListener(mOnRefreshListener);
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
		if(v == pairListView){
			ListView listView = (ListView) parent;
			selectedDevice = (BluetoothDevice) listView
					.getItemAtPosition(position);
			deviceName.setText(selectedDevice.getName());
			deviceMACAddress.setText(selectedDevice.getAddress());
		}
		else{
			selectedDevice = discaDeviceAdapter.getItem(position-1);
			deviceName.setText(selectedDevice.getName());
			deviceMACAddress.setText(selectedDevice.getAddress());
		}
		connectButton.setVisibility(View.VISIBLE);
		deviceImage.setVisibility(View.VISIBLE);
	}

	@Override
	public void onClick(View v) {
		//TODO BLEDeviceConnect
		mCallbackListener.onCallBack(MeasurementActivity.CALLBACK_ID_CONNECT_BLE_FRAGMENT, selectedDevice);
	}

	private void scanLeDevice(final boolean enable) {
		if (enable) {
			// Stops scanning after a pre-defined scan period.
			mHandler.postDelayed(new Runnable() {
				@Override
				public void run() {
					isScanning = false;
					mBluetoothAdapter.stopLeScan(mLeScanCallback);
				}
			}, BleUtil.BLE_SCAN_LIMIT);
			isScanning = true;
			mBluetoothAdapter.startLeScan(mLeScanCallback);
		} else {
			isScanning = false;
			mBluetoothAdapter.stopLeScan(mLeScanCallback);
		}
	}

	// Device scan callback.
	private BluetoothAdapter.LeScanCallback mLeScanCallback =
			new BluetoothAdapter.LeScanCallback() {
				@Override
				public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
					mHandler.obtainMessage(MESSAGE_SCANED_DEVICE, device).sendToTarget();
				}
			};

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			discaDeviceAdapter.add((BluetoothDevice) msg.obj);
			discaDeviceAdapter.notifyDataSetChanged();
		}
	};
}
